package com.lx.composetest.glpaint

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PixelFormat
import android.os.Build
import android.util.AttributeSet
import android.util.Log
import android.view.InputDevice
import android.view.MotionEvent
import android.view.SurfaceHolder
import android.view.SurfaceView
import androidx.graphics.lowlatency.BufferInfo
import androidx.graphics.lowlatency.GLFrontBufferedRenderer
import androidx.graphics.opengl.egl.EGLManager
import androidx.input.motionprediction.MotionEventPredictor
import com.chillingvan.canvasgl.ICanvasGL
import com.chillingvan.canvasgl.glcanvas.GLPaint
import com.lx.composetest.ink.InkRecorder
import java.util.LinkedList

/**
 * Created by Chilling on 2016/11/20.
 */
class SurfaceBubblesView : SurfaceView, SurfaceHolder.Callback {
    private var bitmap: Bitmap? = null
    private val mHolder: SurfaceHolder

    private var isAdd = false

    private var mWidth: Int = 0
    private var mHeight: Int = 0
    private var mPreviousX: Float = 0f
    private var mPreviousY: Float = 0f
    private var mCurrentX: Float = 0f
    private var mCurrentY: Float = 0f
    private val LINE = 0f
    private val PREDICT = 1f
    private val motionPredictor = MotionEventPredictor.newInstance(this)
    private var mFrontBufferRenderer: GLFrontBufferedRenderer<FloatArray>? = null
    private val TAG = "MyGLCanvasTextureView"
    private val paint = GLPaint().apply {
        this.color = Color.RED
        this.lineWidth = 10f
        this.style = Paint.Style.STROKE
    }
    private var currentPosition = FloatArray(4)


    private val mCallbacks = object : GLFrontBufferedRenderer.Callback<FloatArray> {
        private val mMVPMatrix = FloatArray(16)
        private val mProjection = FloatArray(16)
        private val mSceneParams = ArrayList<FloatArray>()
        private var previousWipeLine: FloatArray? = FloatArray(5)
        private var previousLine: FloatArray? = FloatArray(5)
        private var previousLineQueue: LinkedList<FloatArray> = LinkedList<FloatArray>()

        override fun onDrawFrontBufferedLayer(
            eglManager: EGLManager,
            bufferWidth: Int,
            bufferHeight: Int,
            bufferInfo: BufferInfo,
            transform: FloatArray,
            param: FloatArray
        ) {
            Log.i(TAG, "onDrawFrontBufferedLayer: ${Thread.currentThread()}")

        }

        override fun onDrawMultiBufferedLayer(
            eglManager: EGLManager,
            bufferWidth: Int,
            bufferHeight: Int,
            bufferInfo: BufferInfo,
            transform: FloatArray,
            params: Collection<FloatArray>
        ) {
            Log.i(TAG, "onDrawMultiBufferedLayer: ")
        }
    }

    init {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            requestUnbufferedDispatch(InputDevice.SOURCE_CLASS_POINTER)
        }
        setOnTouchListener { _, event ->
            motionPredictor.record(event)
            InkRecorder.addNewTouchEvent(event)
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    this.requestUnbufferedDispatch(event)
                    mCurrentX = event.x
                    mCurrentY = event.y
                }

                MotionEvent.ACTION_MOVE -> {
                    mPreviousX = mCurrentX
                    mPreviousY = mCurrentY
                    mCurrentX = event.x
                    mCurrentY = event.y
                    val line = FloatArray(5).apply {
                        this[0] = mPreviousX
                        this[1] = mPreviousY
                        this[2] = mCurrentX
                        this[3] = mCurrentY
                        this[4] = LINE
                    }
                    mFrontBufferRenderer?.renderFrontBufferedLayer(line)
                    Log.i("InkSurfaceView", "orientation :${event.orientation}")

//                    val motionEventPredicted = motionPredictor.predict()
//                    //处理预测点位
//                    if (motionEventPredicted != null) {
//                        //仅仅使用一半的预测
//                        val predictX = mCurrentX + (motionEventPredicted.x - mCurrentX) / 2f
//                        val predictY =  mCurrentY + (motionEventPredicted.y - mCurrentY) / 2f
//                        //预测点位标识：PREDICT
//                        val predictedSegment = floatArrayOf(
//                            mCurrentX, mCurrentY,
//                            predictX,predictY, PREDICT
//                        )
//                        mFrontBufferRenderer?.renderFrontBufferedLayer(predictedSegment)
//                    }
                }

                MotionEvent.ACTION_CANCEL -> {
                    mFrontBufferRenderer?.commit()
                }

                MotionEvent.ACTION_UP -> {
                    mFrontBufferRenderer?.commit()
                }
            }
            true
        }
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        mWidth = right - left
        mHeight = bottom - top
    }

    override fun onDetachedFromWindow() {
        mFrontBufferRenderer?.release(true) {
        }
        super.onDetachedFromWindow()
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        mFrontBufferRenderer = GLFrontBufferedRenderer(this, mCallbacks)
    }

    constructor(context: Context?) : super(context) {
        mHolder = this.holder
        init()
    }

    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
        mHolder = this.holder
        init()
    }

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        mHolder = this.holder
        init()
    }

    private fun init() {
        setZOrderMediaOverlay(true)
        holder.setFormat(PixelFormat.TRANSLUCENT)
        mHolder.addCallback(this)
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
    }

    private fun doDraw(): Boolean {
        return true
    }


    fun setBitmap(bitmap: Bitmap?) {
        this.bitmap = bitmap
    }

    private fun doOnDraw(canvas: Canvas) {
    }

    fun setAdd(add: Boolean) {
        isAdd = add
    }
}
